/***************************************************************************
 *
 *   copyright            : (C) 2005 Winds of Storm
 *
 *   $Id: db.c,v 1.12 2007/02/10 12:41:26 nathan Exp $
 *
 ***************************************************************************/

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#include "sb.h"

int	bootstrap_db(void) {
	dbconn	= db_connect();
	if (dbconn == NULL) {
		return FALSE;
	} else {
		return TRUE;
	}
}

void	db_noop(DB_CONN *conn) {
	DB_RES *results;
	
	results	= db_query(conn, "SELECT NOW()");
	db_clean_results(results);
}

DB_CONN	*db_connect(void) {
	DB_CONN	*tmpdb = NULL;

#ifdef DBTYPE_MYSQL
	tmpdb	= mysql_init(NULL);
	if (tmpdb == NULL) {
		sb_log(LOG_ERR, "Couldn't initialize DB connection");
		return NULL;
	}

	sb_log(LOG_INFO, "initiating mySQL connection to host '%s'", db_host);
	if (mysql_real_connect(tmpdb, db_host, db_user, db_pass, db_name, 0, NULL, 0) == NULL) {
		sb_log(LOG_ERR, "Connection to MySQL server failed with error #%u: %s", mysql_errno(tmpdb), mysql_error(tmpdb));
		return NULL;
	}

	sb_log(LOG_INFO, "connected to mySQL server '%s@%s:%s'", db_user, db_host, db_name);
	return (DB_CONN *)tmpdb;
#endif
#ifdef	DBTYPE_PQSQL
	char	buffer[MAX_STRING_LENGTH];

	sprintf(buffer, "host=%s dbname=%s user=%s password=%s", db_host, db_name, db_user, db_pass);
	sb_log(LOG_INFO, "initiating PQsql connection to host '%s'", db_host);
	tmpdb	= PQconnectdb(buffer);
	if (PQstatus(tmpdb) == CONNECTION_BAD) {
		sb_log(LOG_ERR, "Connection to PQsql server failed with error: %s", PQerrorMessage(tmpdb));
		return NULL;
	}

	sb_log(LOG_INFO, "connected to PQsql server '%s@%s:%s'", db_user, db_host, db_name);
	return (DB_CONN *)tmpdb;
#endif

	sb_log(LOG_ERR, "reached end-of-sanity clause in db_connect");
	return (DB_CONN *)tmpdb;
}

DB_ROW	db_fetch_row(DB_RES *results, int row_num) {
#ifdef	DBTYPE_MYSQL
	mysql_data_seek(results, row_num);
	return (char **)mysql_fetch_row(results);
#endif
#ifdef	DBTYPE_PQSQL
	// XX : help??
	int i, num_fields;
	char *field_name;
	char *field_value;
	char **row;
	

	num_fields	= PQnfields(results);
	(char *)row	= malloc(num_fields * sizeof(char *));
	for (i = 0; i < num_fields; i++) {
		field_name	= PQfname(results, i);
		field_value	= PQgetvalue(results, row_num, i);
		if (mud_verbosity)
			sb_log(LOG_DEBUG, "db_fetch_row: PQfield #%d = %s, value = %s", i, field_name, field_value);
		row[i]		= field_value;
	}

	return (char **)row;
#endif
	sb_log(LOG_ERR, "reached end-of-sanity clause in db_fetch_row");
	return NULL;
}

DB_RES	*db_query(DB_CONN *conn, char *sql_st) {
#ifdef	DBTYPE_MYSQL
	//sb_log(LOG_INFO, "<<DB>> %s", sql_st);
	if (mysql_query(conn, sql_st) != 0) {
		sb_log(LOG_ERR, "Execution of %s query failed with error #%u: %s", sql_st, mysql_errno(conn), mysql_error(conn));
		return NULL;
	}
	//sb_log(LOG_INFO, "<<DB>> successful query");
	return mysql_store_result(conn);
#endif
#ifdef	DBTYPE_PQSQL
	DB_RES		*result;
	ExecStatusType	resST;

	result	= PQexec(conn, sql_st);
	resST	= PQresultStatus(result);

	if (resST != PGRES_COMMAND_OK && resST != PGRES_TUPLES_OK) {
		sb_log(LOG_ERR, "Execution of '%s' query failed with error %s - %s", sql_st, PQresStatus(resST), PQresultErrorMessage(result));
		return NULL;
	}

	return result;
#endif
	sb_log(LOG_ERR, "reached end-of-sanity clause in db_query");
	return NULL;
}

void	db_clean_results(DB_RES *results) {
#ifdef	DBTYPE_MYSQL
	mysql_free_result(results);
	return;
#endif
#ifdef	DBTYPE_PQSQL
	PQclear(results);
	return;
#endif
	sb_log(LOG_ERR, "reached end-of-sanity clause in db_clean_results");
}

void	db_disconnect(DB_CONN *conn) {
#ifdef	DBTYPE_MYSQL
	mysql_close(conn);
	return;
#endif
#ifdef	DBTYPE_PQSQL
	PQfinish(conn);
	return;
#endif
	sb_log(LOG_ERR, "reached end-of-sanity clause in db_disconnect");
}

int	db_num_rows(DB_RES *results) {
#ifdef  DBTYPE_MYSQL
	return mysql_num_rows(results);
#endif
#ifdef	DBTYPE_PQSQL
	return PQntuples(results);
#endif
	sb_log(LOG_ERR, "reached end-of-sanity clause in db_num_rows");
	return 0;
}

void	db_thread_init(DB_CONN *conn) {
#ifdef	DBTYPE_MYSQL
	mysql_thread_init();
	return;
#endif
	sb_log(LOG_ERR, "reached end-of-sanity clause in db_thread_init");
}

void	db_thread_end(DB_CONN *conn) {
#ifdef	DBTYPE_MYSQL
	mysql_thread_end();
	return;
#endif
	sb_log(LOG_ERR, "reached end-of-sanity clause in db_thread_end");
}
